#!/usr/bin/env python

"""
import Karalhoky as lyrics output module

def Authors():
		triton <triton@portugal-a-programar.org>

def License():
	Do What The Fuck You Want To Public License

def Greets():
	fellow hackers at #gtk+ (GIMP IRC)
	pmg, wrproject at #p@p (PTnet IRC) 
	ic for being a biatch xD
	
def Hate():
	tharis20, _fucker_

def TODO():
	Move window to the center of the screen
"""

import pygtk
pygtk.require('2.0')

import gtk, gobject
from gtk import gdk

import cairo, pango

"Main window that will hold the text widget"
class LyricWindow(gtk.Window):  
	def __init__(self, title):
		gtk.Window.__init__(self)
				
		self.setup_window(title)
		self.add_lyric_widget()
	
	"Sets up the window"
	def setup_window(self, title):
		# set the window title
		self.set_title(title)
		
		# lets get an alpha capable colormap
		colormap = self.get_screen().get_rgba_colormap()        
		self.set_colormap(colormap)

		# set window paintable
		self.set_app_paintable(True)
		
		# remove window from taskbar
		self.set_property("skip-taskbar-hint", True)
		
		# remove decorations
		self.set_decorated(False)   
		
		# set window always-on-top
		self.set_keep_above(True)
		
		# set non-user-resizeable
		self.set_resizable(False)
		
		# allow and connect button press event
		self.add_events(gdk.BUTTON_PRESS_MASK)
		self.connect('button-press-event', self.clicked)
		#self.connect('screen-changed', self.screen_changed)
		self.connect('expose-event', self.do_expose_event)

	"Adds the lyrics text widget to the window"
	def add_lyric_widget(self):
		self.lyric = CairoWidget(self)
		self.lyric.show()
		self.add(self.lyric)
		
	"Handles the moving of the window"
	def clicked(self, widget, event):
		self.begin_move_drag(
			event.button,
			int(event.x_root),
			int(event.y_root),
			event.time)
		return False
				
	def do_expose_event(self, widget, event):
		cr = event.window.cairo_create ()
		cr.set_operator (cairo.OPERATOR_SOURCE)
		cr.set_source_rgba (0, 0, 0, 0)
		cr.rectangle (event.area)
		cr.fill ()

		gtk.Container.do_expose_event (self, event)

"Main widget used for drawing the lyrics"
class CairoWidget(gtk.DrawingArea):
	def __init__(self, window):
		gtk.DrawingArea.__init__(self)
		
		# create the context menu
		self.settings = Settings(window)
		
		self.set_app_paintable(True)
		
		# set text stuff
		self.setup_pango("lyrics here")
				
		# hardwire all the events
		self.connect('expose-event', self.expose_event)
		self.connect('configure-event', self.configure_event)
		
		self.add_events(gdk.BUTTON_PRESS_MASK)
		self.connect('button-press-event', self.popup_menu)
		
	"Handles the popup menu when user right-clicks"
	def popup_menu(self, widget, event):
		# if it was a right click...
		if event.button == 3:
			# spawn a context menu! 
			self.settings.popup(
				None, None, None,
				event.button, event.time)
			return True
		return False
	 
	"Sets up the Pango layout"
	def setup_pango(self, text):
		self.layout = self.create_pango_layout(text);
		self.set_font()
		
	def set_font(self):
		self.font_desc = pango.FontDescription(self.settings.font)
		self.layout.set_font_description(self.font_desc)
		
	"Callback for the configure event"
	def configure_event(self, widget, event):
		self.resize()
		return True
	
	"Resizes the widget"
	def resize(self):
		size = self.layout.get_pixel_size()
		size = (size[0]*2,size[1])
		self.set_size_request(*size)
				
	"Set the lyric text"
	def set_text(self, text):
		self.layout.set_text(text)
		# force redraw
		self.queue_draw()
	
	"Handles the expose (draw request) event"
	def expose_event(self, widget, event):
		# create a new graphics context
		self.gc = self.window.new_gc()
		self.ctx = self.window.cairo_create()

		self.do_transparent()
		self.window.draw_layout(self.gc, 0, 0, self.layout)
		
		# handle the mask
		#pm = gtk.gdk.Pixmap(None, width, height, 1)
		#self.window.input_shape_combine_mask(pm, 0, 0)

		return False
		
	"Makes the widget transparent"
	def do_transparent(self):
		self.ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0)
		self.ctx.set_operator(cairo.OPERATOR_SOURCE)
		self.ctx.paint()

"Context menu used to change settings"
class Settings(gtk.Menu):
	def __init__(self, window):
		gtk.Menu.__init__(self)
		
		# set up the default settings
		self.default_settings()

		# store the window handle
		self.win = window

		self.add_aot_item()
		self.add_font_item()
		
		# show all menu items
		self.show_all()
	
	"Sets some sensible default settings"
	def default_settings(self):
		self.font = "Sans 13"

	"Adds the always-on-top item to the menu"
	def add_aot_item(self):
		# add a always-on-top checkbox
		aot = gtk.CheckMenuItem("Always on Top")
		aot.set_active(True)
		aot.connect("toggled", self.aot_callback)
		self.append(aot)
	
	"Adds the font-select item to the menu"
	def add_font_item(self):
		# add a font selection item
		font = gtk.MenuItem("Select font...")
		font.connect("activate", self.font_callback)
		self.append(font)
		
		#TODO: first time, ask for wanted font
	
	"Handles the callback for the font selection dialog"
	def font_callback(widget, item):
		def handle_ok(button, settings, dlg):
			settings.font = dlg.get_font_name()
			widget = settings.win.lyric
			widget.set_font()
			widget.queue_draw()
			widget.resize()
			dlg.destroy()
			
		dlg = gtk.FontSelectionDialog("Select a font")
		dlg.set_modal(True)
		dlg.ok_button.connect("clicked", handle_ok, widget, dlg)
		dlg.cancel_button.connect_object("clicked", lambda w: w.destroy(), dlg)
		dlg.show()
	
	"Handles the callback for the always-on-top check-box"
	def aot_callback(widget, item):
		widget.win.set_keep_above(item.get_active())

if __name__ == "__main__":
	window = LyricWindow('Karalhoky')
	window.present()
#    print dir(window)
	try:
		gtk.main()
	except KeyboardInterrupt:
		pass

